﻿using AutoMapper;
using B.S.BaseData.Domain.Entities.Meeting;
using B.S.BaseData.ErrorCode;
using B.S.BaseData.ErrorCode.ErrorCodes;
using B.S.BaseData.Infrastructure.Interfaces;
using B.S.DataBase.EFCoreServiers.Dtos;
using B.S.DataBase.EFCoreServiers.Dtos.MeetingApprovals;
using B.S.DataBase.EFCoreServiers.IServices.Meetings;
using Microsoft.EntityFrameworkCore;
using NPOI.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace B.S.DataBase.EFCoreServiers.Services.Meetings
{
    public class MeetingApprovalServices : IMeetingApprovalServices
    {
        private readonly IMeetingApprovalRepository meetingApproval;
        private readonly IMapper mapper;
        private readonly IMeetingReservationRepository meetingReservation;

        public MeetingApprovalServices(IMeetingApprovalRepository meeting, IMapper mapper, IMeetingReservationRepository meetingReservation)
        {
            this.meetingApproval = meeting;
            this.mapper = mapper;
            this.meetingReservation = meetingReservation;
        }
        /// <summary>
        /// 审批
        /// </summary>
        /// <param name="processDto"></param>
        /// <returns></returns>
        public async Task<ApiResult> ApprovalProcess(MeetingApprovalProcessDto processDto)
        {
            //查找到当前需要审核的会议申请  显示的时候做判断  审批列表值显示当前审核人的需要审批的列表  并且只查看需要审批的 审批过的不显示
            var meetingApprovalList = await meetingApproval.GetAll().FirstOrDefaultAsync(x => x.MeetingApprovalId == processDto.MeetingApprovalId);
            if (meetingApprovalList == null)
            {
                return ApiResult.Fail("未找到该会议申请", StatusCodeEnum.Fail);
            }

            //查找到需要审批的 会议预约信息
            var meetingReservationList = await meetingReservation.GetAll().FirstOrDefaultAsync(x => x.MeetingReservationId == meetingApprovalList.MeetingReservationId);
            if (meetingReservationList == null)
            {
                return ApiResult.Fail("未找到相关会议预约信息", StatusCodeEnum.Fail);
            }

            //开启分布式事务
            using (var tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    StatusCodeEnum resultCode;

                    //如果是通过审批
                    if (processDto.Result == "通过")
                    {
                        //更新会议预约状态  预约审批完成  会议待开始
                        meetingReservationList.Status = MeetingStatus.Solved;
                        //更新审批状态为已通过 
                        meetingApprovalList.State = 1;
                        meetingApprovalList.Result = processDto.Result;
                        meetingApprovalList.ApprovalThing = processDto.ApprovalThing;

                        // 保存审批记录更改
                        await meetingApproval.UpdateAsync(meetingApprovalList);
                        // 保存会议预约状态更改
                        //await meetingReservation.UpdateAsync(meetingReservationList);

                        resultCode = StatusCodeEnum.ApprovalSuccess;
                    }
                    else if (processDto.Result == "驳回")
                    {
                        //如果是拒绝审批，更新会议预约状态为未通过
                        meetingReservationList.Status = MeetingStatus.Reject;
                        //更新审批状态为已拒绝
                        meetingApprovalList.State = 2;
                        meetingApprovalList.Result = processDto.Result;
                        meetingApprovalList.ApprovalThing = processDto.ApprovalThing;

                        // 先保存会议预约状态更改
                        await meetingReservation.UpdateAsync(meetingReservationList);

                        //驳回需要删除审批记录，会议申请也需要重新提交
                        //await meetingApproval.DeleteAsync(meetingApprovalList);

                        resultCode = StatusCodeEnum.ApprovalFail;
                    }
                    else
                    {
                        resultCode = StatusCodeEnum.Ok;
                    }

                    // 完成事务
                    tran.Complete();

                    // 返回结果
                    return ApiResult.Success(resultCode);
                }
                catch (Exception ex)
                {
                    // 事务会自动回滚
                    return ApiResult.Fail("审批处理失败：" + ex.Message, StatusCodeEnum.Fail);
                }
            }
        }
        /// <summary>
        /// 重新提交会议预约申请
        /// </summary>
        /// <param name="MeetingReservationId"></param>
        /// <returns></returns>
        public async Task<ApiResult> ApprovalResubmit(int MeetingReservationId)
        {
            //查询到需要重新提交的会议预约信息
            var meetingReservationList = await meetingReservation.GetAsync(x => x.MeetingReservationId == MeetingReservationId);
            if (meetingReservationList == null)
            {
                return ApiResult.Fail("未找到相关会议预约信息", StatusCodeEnum.Fail);
            }
            //根据预约id查到需要重新提交的审批记录
            var meetingApprovalList = await meetingApproval.GetAsync(x => x.MeetingReservationId == MeetingReservationId);

            //开启分布式事务
            using (var tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    meetingReservationList.Status = MeetingStatus.Pending;//修改为 待审核
                    meetingApprovalList.State = 0;//修改为 待审核
                    await meetingReservation.UpdateAsync(meetingReservationList);
                    tran.Complete();
                    return ApiResult.Success(StatusCodeEnum.ApprovalResubmit);//代表重新提交成功
                }
                catch (Exception)
                {
                    tran.Dispose();
                    throw;
                }
            }
        }

        /// <summary>
        /// 审批列表
        /// </summary>
        /// <param name="queryDto"></param>
        /// <returns></returns>
        public async Task<ApiResult<ApiPaging<GetMeetingApprovalResponseDto>>> GetMeetingApprovalListAsync(GetMeetingApprovalDto queryDto)
        {
            //只显示需要你审批的审批列表  
            var Approval = await meetingApproval.GetAll().Where(x => x.UserId.Contains(queryDto.UserId) && x.State == 0).ToListAsync();
            //或者发起人是你自己的审批列表 
            var Reservation = await meetingReservation.GetAll().Where(x => x.HostId.Contains(queryDto.UserId)).ToListAsync();

            // HasValue可空的  DateTime属性，判断是否有值
            var enddata = queryDto.MeetingDate.HasValue ? queryDto.MeetingDate.Value.AddDays(1) : (DateTime?)null;

            var list = from a in Approval
                       join b in Reservation on a.MeetingReservationId equals b.MeetingReservationId
                       where (string.IsNullOrEmpty(queryDto.Subject) || b.Subject.Contains(queryDto.Subject)) &&
                           (string.IsNullOrEmpty(queryDto.MeetingRoomName) || b.MeetingRoomName.Contains(queryDto.MeetingRoomName)) &&
                           (queryDto.MeetingDate == null || (b.MeetingDate >= queryDto.MeetingDate && b.MeetingDate < enddata))
                       select new GetMeetingApprovalResponseDto
                       {
                           MeetingApprovalId = a.MeetingApprovalId,
                           MeetingReservationId = a.MeetingReservationId,
                           Result = a.Result,
                           ApprovalThing = a.ApprovalThing,
                           State = a.State,
                           UserId = a.UserId,
                           AccessControlEnabled = b.AccessControlEnabled,
                           Content = b.Content,
                           EndTime = b.EndTime,
                           MeetingDate = b.MeetingDate,
                           MeetingRoomId = b.MeetingRoomId,
                           MeetingRoomName = b.MeetingRoomName,
                           StartTime = b.StartTime,
                           Subject = b.Subject,
                           HostId = b.HostId,
                           HostName = b.HostName,
                           IsRemoteMeeting = b.IsRemoteMeeting,
                           Participants = b.Participants,
                           RequireSignIn = b.RequireSignIn,
                           SendSmsNotification = b.SendSmsNotification,
                           Status = b.Status
                       };

            int count = list.Count();
            int totalPage = (int)Math.Ceiling((double)count / queryDto.pageSize);
            list = list.Skip((queryDto.pageIndex - 1) * queryDto.pageSize).Take(queryDto.pageSize);

            var dto = mapper.Map<IList<GetMeetingApprovalResponseDto>>(list);

            var apiPaging = new ApiPaging<GetMeetingApprovalResponseDto>(count, totalPage, dto);

            return ApiResult<ApiPaging<GetMeetingApprovalResponseDto>>.Success(apiPaging, StatusCodeEnum.Ok);
        }













    }
}



